<template>
  <el-dialog v-model="dialogVisible" :title="parameter.title" width="680px" lock-scroll destroy-on-close draggable>
    <el-form ref="formRef" :model="parameter.user" :rules="rules" label-width="100px" label-suffix=" :">
      <el-form-item label="登录账号" prop="account">
        <el-input v-model="parameter.user.account" placeholder="请填写登录账号" clearable />
      </el-form-item>
      <el-row>
        <el-col :span="12">
          <el-form-item label="真实姓名" prop="name">
            <el-input v-model="parameter.user.name" placeholder="请填写真实姓名" clearable />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="昵称" prop="nickName">
            <el-input v-model="parameter.user.nickName" placeholder="请填写昵称" clearable />
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="用户性别" prop="sex">
        <el-select v-model="parameter.user.sex" placeholder="请选择用户性别" clearable>
          <el-option v-for="item in userSexConst" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="所属机构" prop="orgId">
        <el-cascader
          v-model="parameter.user.orgId"
          :options="formInline.orgOptions"
          :props="{ checkStrictly: true, emitPath: false }"
          style="width: 100%"
          clearable
          filterable
          placeholder="请选择上级目录"
        >
          <template #default="{ node, data }">
            <span>{{ data.label }}</span>
            <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
          </template>
        </el-cascader>
      </el-form-item>
      <el-form-item label="角色集合" prop="roleIds">
        <el-select v-model="parameter.user.roleIds" placeholder="请分配用户角色" multiple clearable>
          <el-option v-for="item in formInline.roleOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="联系电话" prop="phone">
        <el-input v-model="parameter.user.phone" placeholder="请填写联系电话" clearable />
      </el-form-item>
      <el-form-item label="电子邮箱" prop="email">
        <el-input v-model="parameter.user.email" placeholder="请填写电子邮箱" clearable />
      </el-form-item>
      <el-form-item label="自我介绍" prop="selfIntroduction">
        <el-input v-model="parameter.user.selfIntroduction" type="textarea" placeholder="请填写自我介绍" clearable />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="handleSubmit">提交</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import type { FormInstance, FormRules } from "element-plus";
import type { ResultData, Option, SysUser } from "@/api/interface";
import { ref, reactive, watch } from "vue";
import { userSexConst } from "@/utils/dict";
import { FormEnum } from "@/enums/formEnum";
import { ElMessage } from "element-plus";
import { getOrgCascaderOptionApi } from "@/api/modules/system/org";
import { getRoleOptionApi } from "@/api/modules/system/role";

defineOptions({
  name: "SystemUserEdit"
});

/** 系统用户 */
interface EditProps {
  /** 标题 */
  title: string;
  /** 待编辑的用户 */
  user: Partial<SysUser.Form>;
  /** 获取表格数据的Api */
  getTableList?: () => void;
  /** 提交表单的Api */
  submitApi?: (params: any) => Promise<ResultData<boolean>>;
}
/** 表单内联数据 */
interface FormInline {
  /** 机构选项 */
  orgOptions: Option.CascadeOption[];
  /** 角色选项 */
  roleOptions: Option.SelectOption[];
}

/** 表单实例 */
const formRef = ref<FormInstance>();
/** dialog 状态 */
const dialogVisible = ref(false);
/** 表单验证规则 */
const rules = reactive<FormRules>({
  account: [{ required: true, message: "请输入登录账号", trigger: "blur" }],
  name: [{ required: true, message: "请输入用户名称", trigger: "blur" }],
  sex: [{ required: true, message: "请选择用户性别", trigger: "blur" }],
  orgId: [{ required: true, message: "请选择所属机构", trigger: "blur" }],
  roleIds: [{ required: true, message: "请选择角色", trigger: "blur" }]
});
/** 父组件传过来的参数 */
const parameter = ref<EditProps>({
  title: "",
  user: {}
});
/** 表单内联数据 */
const formInline = reactive<FormInline>({
  orgOptions: [],
  roleOptions: []
});

/**
 * 接收父组件参数
 *
 * @param params 父组件传过来的参数
 * @returns void
 */
const acceptParams = (params: EditProps) => {
  parameter.value = params;
  dialogVisible.value = true;
};

/**
 * 初始化表单
 *
 * 1. 重置表单
 * 2. 获取机构和角色选项
 *
 * @returns void
 */
const initFormInline = () => {
  formRef.value?.resetFields();

  // 获取机构和角色选项
  Promise.all([getOrgCascaderOptionApi(), getRoleOptionApi()]).then(([org, role]) => {
    formInline.orgOptions = org.data;
    formInline.roleOptions = role.data;
  });
};

/**
 * 提交表单
 *
 * 1. 校验表单
 * 2. 表单数据处理
 * 3. 提交表单
 * 4. 提交结果处理
 * 5. 异常处理
 *
 * @returns void
 */
const handleSubmit = () => {
  formRef.value
    // 1. 校验表单
    ?.validate()
    // 2. 表单数据处理
    .then(() => {
      parameter.value.user = {
        id: parameter.value.user.id || FormEnum.EmptyId,
        account: parameter.value.user.account,
        name: parameter.value.user.name,
        nickName: parameter.value.user.nickName || parameter.value.user.name,
        sex: parameter.value.user.sex || 0,
        orgId: parameter.value.user.orgId || FormEnum.EmptyId,
        roleIds: parameter.value.user.roleIds || [],
        phone: parameter.value.user.phone || "",
        email: parameter.value.user.email || "",
        selfIntroduction: parameter.value.user.selfIntroduction || ""
      };

      return parameter.value.user;
    })
    // 3. 提交表单
    .then(user => {
      return parameter.value.submitApi!(user);
    })
    // 4. 提交结果处理
    .then(({ data }) => {
      if (data) {
        ElMessage.success({ message: `${parameter.value.title}成功！` });
        parameter.value.getTableList!();
        dialogVisible.value = false;
      } else {
        ElMessage.error({ message: `${parameter.value.title}失败！` });
      }
    })
    // 5. 异常处理
    .catch((error: Error) => {
      if (error.message) ElMessage.error({ message: `${parameter.value.title}异常：${error.message}` });
      else ElMessage.error({ message: "请检查表单数据是否填写完整！" });
    });
};

// 监听 dialogVisible 的变化
watch(dialogVisible, val => {
  if (val) {
    initFormInline();
  }
});

// 暴露给父组件的属性和方法
defineExpose({
  acceptParams
});
</script>
